package io.yuncheng.modules.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.yuncheng.common.config.DictConfig;
import io.yuncheng.common.exception.RRException;
import io.yuncheng.common.utils.*;
import io.yuncheng.common.utils.Constant;
import io.yuncheng.common.utils.LogTypeConstant;
import io.yuncheng.common.utils.Query;
import io.yuncheng.common.utils.SysDictConstant;
import io.yuncheng.modules.sys.dao.SubApplicationDao;
import io.yuncheng.modules.sys.entity.SubApplicationEntity;
import io.yuncheng.modules.sys.entity.SubApplicationEntityVo;
import io.yuncheng.modules.sys.entity.SubApplicationVo;
import io.yuncheng.modules.sys.entity.SysDeptEntity;
import io.yuncheng.modules.sys.service.SubApplicationService;
import io.yuncheng.modules.sys.service.SysDeptService;
import io.yuncheng.modules.sys.service.SysOperationLogService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Service("subApplicationService")
public class SubApplicationServiceImpl extends ServiceImpl<SubApplicationDao, SubApplicationEntity> implements SubApplicationService {
    @Autowired
    private SysDeptService sysDeptService;
    @Resource
    private SysOperationLogService sysOperationLogService;
    @Resource
    private DictConfig dictConfig;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Object deptId = params.get("deptId");
        Object parentDeptId = params.get("parentDeptId");
        Object appStatus = params.get("appStatus");
        IPage<SubApplicationEntity> page = this.page(
                new Query<SubApplicationEntity>().getPage(params), new QueryWrapper<SubApplicationEntity>()
                        .eq(deptId != null, "dept_id", deptId)
                        .eq(parentDeptId != null, "parent_dept_id", parentDeptId)
                        .eq(appStatus != null, "app_status", appStatus)
        );
        List<SubApplicationEntity> records = page.getRecords();
        List<Map> voList = records.stream().map(a -> {
                    Map<String,Object> mapValue = buildByEntity(a);
                    SysDeptEntity byId = sysDeptService.getById(a.getParentDeptId());
                    if (byId != null) {
                        mapValue.put("ParentDeptName",byId.getName());
                        mapValue.put("parentDeptName",byId.getName());
                    }
                    return mapValue;
                }
        ).collect(Collectors.toList());
        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(voList);
        return pageUtils;
    }

    @Override
    public PageUtils queryConfirmPage(Map<String, Object> params) {
        params.putIfAbsent("appStatus", Constant.StatusType.NORMAL.getValue());
        return queryPage(params);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveAppAndDept(SubApplicationEntity subApplication) {
        SysDeptEntity byId = sysDeptService.getById(subApplication.getParentDeptId());
        sysDeptService.checkDept(byId.getParentId(),"的数据");
        if (byId == null || !byId.getType().equals(Constant.DeptTypeEnum.DEPT_2.getValue())) {
            throw new RRException("请选定正确的机构");
        }
        SysDeptEntity sysDeptEntity = sysDeptService.saveByApp(subApplication);
        subApplication.setDeptId(sysDeptEntity.getDeptId());
        //修改应用名称和部门名称对应
        if(ObjectUtils.isEmpty(subApplication.getAppDesc())){
            subApplication.setAppDesc("");
        }
        subApplication.setCreateTime(new Date());
        save(subApplication);
        sysOperationLogService.saveLog(LogTypeConstant.SOURCE,"注册应用\"" + subApplication.getAppName()+"\",ID\"" +subApplication.getAppId() +"\"");
        return true;
    }

    @Override
    public SubApplicationEntity queryByDeptId(Long deptId) {
        return baseMapper.selectOne(new QueryWrapper<SubApplicationEntity>().eq("dept_id", deptId));
    }

    @Override
    public List<SubApplicationEntity> queryByParentDeptId(Long deptId) {
        return baseMapper.selectList(new QueryWrapper<SubApplicationEntity>().eq("parent_dept_id", deptId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean writeOnAndOff(Long appId, Constant.StatusType statusType) {
        //状态修改
        SubApplicationEntity byId = getById(appId);
        byId.setAppStatus(statusType.getValue());
        updateById(byId);
        SysDeptEntity deptEntity = sysDeptService.getById(byId.getDeptId());
        sysDeptService.checkByParentDeptId(deptEntity.getParentId(),"的数据");
        deptEntity.setStatus(statusType.getValue());
        sysDeptService.updateById(deptEntity);
        return Boolean.TRUE;
    }

    private  Map<String,Object>  buildByEntity(SubApplicationEntity entity) {
        String s = JSON.toJSONString(entity);
        SubApplicationVo subApplicationVo = JSON.parseObject(s, SubApplicationVo.class);
        subApplicationVo.setAppLevelName(dictConfig.getSysDictValue(SysDictConstant.APP_LEVEL, String.valueOf(entity.getAppLevel())));
        subApplicationVo.setAppTypeName(dictConfig.getSysDictValue(SysDictConstant.APP_SOURCE_TYPE, String.valueOf(entity.getAppType())));
        String arithList = subApplicationVo.getArithList();
        Map<String,Object> mapValue = JSON.parseObject(JSON.toJSONString(subApplicationVo), Map.class);
        if(!ObjectUtils.isEmpty(arithList)){
            String[] split = arithList.split(",");
            for (String s1 : split) {
                String sysDictValue = dictConfig.getSysDictValue(SysDictConstant.ARITH, s1);
                if(!ObjectUtils.isEmpty(sysDictValue)){
                    mapValue.put(sysDictValue.toLowerCase(),s1);
                    mapValue.put(sysDictValue.toLowerCase()+"Name",sysDictValue);
                }
            }

        }
        return mapValue;
    }

    /**
     * 过滤权限的应用查询
     *
     * @param params
     * @return
     */
    @Override
    public List<SubApplicationEntityVo> queryConfirmList(Map<String, Object> params) {
        List<SysDeptEntity> list = sysDeptService.queryList(new HashMap<>(4));
        List<Long> collect = list.stream().map(SysDeptEntity::getDeptId).collect(Collectors.toList());
        Map<Long, SysDeptEntity> deptMap = list.stream().collect(Collectors.toMap(a -> a.getDeptId(), a -> a, (k1, k2) -> k1));
        Object[] objects = collect.toArray();
        List<SubApplicationEntity> subApplicationEntities = list(new QueryWrapper<SubApplicationEntity>().in("dept_id", objects).eq("app_status", Constant.StatusType.NORMAL.getValue()));
        BeanUtils.copyProperties("",new SubApplicationEntityVo());
        List<SubApplicationEntityVo> applicationEntityVoList = new ArrayList<>();
        for (SubApplicationEntity a : subApplicationEntities) {
            SubApplicationEntityVo subApplicationEntityVo = new SubApplicationEntityVo();
            BeanUtils.copyProperties(a,subApplicationEntityVo,SubApplicationEntityVo.class);
            applicationEntityVoList.add(subApplicationEntityVo);
            SysDeptEntity sysDeptEntity = deptMap.get(subApplicationEntityVo.getDeptId());
            subApplicationEntityVo.setParentDeptName(sysDeptEntity.getParentName());
        }


        return applicationEntityVoList;
    }
    @Override
    public List<SubApplicationEntity> queryConfirmListByEntity(SubApplicationEntity entity) {
        List<SubApplicationEntity> subApplicationEntities = list(new QueryWrapper<SubApplicationEntity>().eq("app_status", Constant.StatusType.NORMAL.getValue()).setEntity(entity));
        return subApplicationEntities;
    }
    @Override
    public List<SubApplicationEntity> queryConfirmListByParentDeptIdAndAppType(Long parentDeptId,Integer appType) {
        SubApplicationEntity entity = new SubApplicationEntity();
        entity.setAppType(appType);
        entity.setParentDeptId(parentDeptId);
        return queryConfirmListByEntity(entity);
    }

    @Override
    public List<SubApplicationEntity> queryConfirmListByRootDeptIdAndType(Long deptId,Integer appType)  {
        List<SubApplicationEntity> queryList= new ArrayList<>();
        List<SysDeptEntity> sysDeptEntities = sysDeptService.queryLevelTwoListByDept(deptId);
        sysDeptEntities.forEach(a->queryList.addAll(queryConfirmListByParentDeptIdAndAppType(a.getDeptId(),appType)));
        return queryList;
    }



}
